package com.xh3140.xwidget.dialog;

import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.Size;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.MutableLiveData;

import com.xh3140.xwidget.dialog.callback.ConfigParamsCallback;
import com.xh3140.xwidget.dialog.callback.ConfigViewCallback;
import com.xh3140.xwidget.dialog.listener.OnClickButtonListener;
import com.xh3140.xwidget.dialog.params.InputParams;
import com.xh3140.xwidget.dialog.view.FooterView;
import com.xh3140.xwidget.dialog.view.HeaderView;
import com.xh3140.xwidget.dialog.view.InputView;
import com.xh3140.xwidget.dialog.view.RootView;

/**
 * 输入对话框
 */
@SuppressWarnings("unused")
public final class InputDialog extends BaseDialog<InputView> {
  private InputParams mInputParams;
  private OnClickButtonListener<InputDialog> mOnClickButtonListener;

  @Override
  protected RootView<InputView> createRootView(@NonNull Context context) {
    final InputDialog dialog = this;
    return new RootView<InputView>(context) {
      @Override
      protected HeaderView createHeaderView(@NonNull Context context) {
        return new HeaderView(context).configView(mHeaderParams);
      }

      @Override
      protected InputView createBodyView(@NonNull Context context) {
        return new InputView(context).configView(mInputParams);
      }

      @Override
      protected FooterView createFooterView(@NonNull Context context) {
        return new FooterView(context).configView(dialog, mFooterParams, mOnClickButtonListener);
      }
    };
  }

  @Override
  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    ViewModel.getDefault(this, ViewModel.class).configInputDialogParams(this);
    return super.onCreateView(inflater, container, savedInstanceState);
  }

  @Override
  public void onStart() {
    super.onStart();
    // 是否弹出输入法
    if (mInputParams.showSoft) {
      showSoftInput();
    }
  }

  /**
   * 获取输入框文本
   */
  @Nullable
  public Editable getInputText() {
    return requireRootView().requireBodyView().getText();
  }

  /**
   * 数据状态保存
   * 由于屏幕方向旋转等情况会导致构建数据丢失，所以需要保存
   */
  public static final class ViewModel extends BaseDialog.ViewModel {
    private final MutableLiveData<InputParams> mInputParamsData = new MutableLiveData<>();
    private final MutableLiveData<OnClickButtonListener<InputDialog>> mOnClickButtonListenerData = new MutableLiveData<>();

    private void configInputDialogParams(@NonNull final InputDialog dialog) {
      configBaseDialogParams(dialog);
      if (dialog.mInputParams == null) {
        dialog.mInputParams = mInputParamsData.getValue();
      } else {
        mInputParamsData.postValue(dialog.mInputParams);
      }
      if (dialog.mOnClickButtonListener == null) {
        dialog.mOnClickButtonListener = mOnClickButtonListenerData.getValue();
      } else {
        mOnClickButtonListenerData.postValue(dialog.mOnClickButtonListener);
      }
    }
  }

  /**
   * 输入对话框构建器
   * 设置输入对话框属性
   */
  public static final class Builder extends BaseDialog.Builder<InputDialog, Builder> {
    /**
     * 对话框输入主体视图配置属性
     */
    private final InputParams mInputParams;

    public Builder(@NonNull Context context) {
      super(context);
      mInputParams = new InputParams(context);
    }

    public Builder(@NonNull FragmentActivity activity) {
      super(activity);
      mInputParams = new InputParams(mDialogParams.context);
    }

    public Builder(@NonNull Fragment fragment) {
      super(fragment);
      mInputParams = new InputParams(mDialogParams.context);
    }

    /**
     * 构建对话框
     * 这个方法应该在所有配置结束后调用
     */
    @Override
    public InputDialog build() {
      final InputDialog dialog = new InputDialog();
      dialog.mDialogParams = mDialogParams;
      dialog.mHeaderParams = mHeaderParams;
      dialog.mFooterParams = mFooterParams;
      dialog.mInputParams = mInputParams;
      dialog.mOnClickButtonListener = mOnClickButtonListener;
      return dialog;
    }

    /**
     * 配置输入主体视图属性
     *
     * @param callback 配置回调
     */
    public Builder configInputParams(@NonNull ConfigParamsCallback<InputParams> callback) {
      callback.callback(mInputParams);
      return this;
    }

    /**
     * 设置输入主体视图输入类型
     *
     * @param type 输入类型
     */
    public Builder setInputType(int type) {
      mInputParams.inputType = type;
      return this;
    }

    /**
     * 设置输入主体视图文本
     *
     * @param text 文本
     */
    public Builder setInputText(@Nullable CharSequence text) {
      mInputParams.text = text;
      return this;
    }

    /**
     * 设置输入主体视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public Builder setInputTextSize(float textSize) {
      mInputParams.textSize = textSize;
      return this;
    }

    /**
     * 设置输入主体视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public Builder setInputTextColor(@ColorInt int textColor) {
      mInputParams.textColor = textColor;
      return this;
    }

    /**
     * 设置输入主体视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public Builder setInputTypeface(int typeface) {
      mInputParams.typeface = typeface;
      return this;
    }

    /**
     * 设置输入主体视图提示语文本
     *
     * @param text 提示语文本
     */
    public Builder setInputHint(@Nullable CharSequence text) {
      mInputParams.hint = text;
      return this;
    }

    /**
     * 设置输入主体视图提示语文本颜色
     *
     * @param textColor 文本颜色
     */
    public Builder setInputHintColor(@ColorInt int textColor) {
      mInputParams.hintColor = textColor;
      return this;
    }

    /**
     * 设置输入主体视图文本位置
     *
     * @param gravity 位置
     */
    public Builder setInputGravity(int gravity) {
      mInputParams.gravity = gravity;
      return this;
    }

    /**
     * 设置输入主体视图是否单行
     *
     * @param singleLine 标志
     */
    public Builder setInputSingleLine(boolean singleLine) {
      mInputParams.singleLine = singleLine;
      return this;
    }

    /**
     * 设置输入主体视图最大行数
     *
     * @param maxLines 最大行数
     */
    public Builder setInputMaxLines(int maxLines) {
      mInputParams.maxLines = maxLines;
      return this;
    }

    /**
     * 设置输入主体视图每行最大显示长度
     *
     * @param maxEms 最大显示长度
     */
    public Builder setInputMaxEms(int maxEms) {
      mInputParams.maxEms = maxEms;
      return this;
    }

    /**
     * 设置输入主体视图最大输入长度
     *
     * @param maxLength 最大输入长度
     */
    public Builder setInputMaxLength(int maxLength) {
      mInputParams.maxLength = maxLength;
      return this;
    }

    /**
     * 设置输入主体视图边框线条粗细 px
     *
     * @param width 边框线条粗细
     */
    public Builder setInputStrokeWidth(@Px int width) {
      mInputParams.strokeWidth = width;
      return this;
    }

    /**
     * 设置输入主体视图边框线条颜色 argb
     *
     * @param color 边框线条颜色
     */
    public Builder setInputStrokeColor(@ColorInt int color) {
      mInputParams.strokeColor = color;
      return this;
    }

    /**
     * 设置输入主体视图圆角半径 px
     *
     * @param radius 圆角半径
     */
    public Builder setInputRadius(@Px int radius) {
      mInputParams.radius = radius;
      return this;
    }

    /**
     * 设置输入主体视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public Builder setInputBackgroundColor(@ColorInt int backgroundColor) {
      mInputParams.backgroundColor = backgroundColor;
      return this;
    }

    /**
     * 设置输入主体视图资源ID
     *
     * @param resId 资源ID
     */
    public Builder setInputBackgroundResourceId(@DrawableRes int resId) {
      mInputParams.backgroundResource = resId;
      return this;
    }

    /**
     * 设置输入主体视图显示时是否弹出输入法
     *
     * @param showSoft 标识
     */
    public Builder setInputShowSoft(boolean showSoft) {
      mInputParams.showSoft = showSoft;
      return this;
    }

    /**
     * 设置输入视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public Builder setInputPadding(@Nullable @Size(4) int[] padding) {
      mInputParams.padding = padding;
      return this;
    }

    /**
     * 设置输入视图内边距
     *
     * @param padding 边距 px
     */
    public Builder setInputPadding(@Px int padding) {
      return setInputPadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置输入视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public Builder setInputPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setInputPadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置输入视图外边距
     * 格式：[start, top, end, bottom] px
     *
     * @param margins 边距
     */
    public Builder setInputMargins(@Nullable @Size(4) int[] margins) {
      mInputParams.margins = margins;
      return this;
    }

    /**
     * 设置输入视图外边距
     *
     * @param margins 边距 px
     */
    public Builder setInputMargins(@Px int margins) {
      return setInputMargins(new int[]{margins, margins, margins, margins});
    }

    /**
     * 设置输入视图外边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public Builder setInputMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setInputMargins(new int[]{left, top, right, bottom});
    }

    /**
     * 设置输入主体视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public Builder setInputViewCallback(@Nullable ConfigViewCallback<InputView> callback) {
      mInputParams.callback = callback;
      return this;
    }
  }
}
